﻿/*
  The contents of this file are subject to the Mozilla Public License Version
  1.1 (the "License"); you may not use this file except in compliance with
  the License. You may obtain a copy of the License at 
  http://www.mozilla.org/MPL/ 
  
  Software distributed under the License is distributed on an "AS IS" basis,
  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  for the specific language governing rights and limitations under the License. 
  
  The Original Code is [eden: ECMAScript data exchange notation AS3]. 
  
  The Initial Developer of the Original Code is
  Zwetan Kjukov <zwetan@gmail.com>.
  Portions created by the Initial Developer are Copyright (C) 2004-2011
  the Initial Developer. All Rights Reserved.
  
  Contributor(s):
  Marc Alcaraz <ekameleon@gmail.com>.
  
*/

package library.eden
{
    import core.dump;
    
    /**
    * Configures the eden library.
    */
    public class EdenConfigurator
    {
        private var _config:Object;
        
        /**
         * Creates a new EdenConfigurator instance.
         * @param config This argument initialize the configurator with a generic object.
         */
        public function EdenConfigurator( config:Object )
        {
            _config = {};
            
            if( config )
            {
                load( config );
            }
        }
        
        /**
        * Copy all properties in the specified passed-in object in the internal config object of the Configurator.
        */
        public function load( config:Object ):void
        {
            for( var member:String in config )
            {
                _config[member] = config[member] ;
            }
        }
        
        public function toSource():String { return dump( _config, true ); }
        
        /** Allows to throw errors from the eden parser. */
        public function get enableErrorChecking():Boolean { return _config.enableErrorChecking; }
        
        /** @private */
        public function set enableErrorChecking( value:Boolean ):void { _config.enableErrorChecking = value; }
        
        /** Allows to use aliases in the eden parser. */
        public function get allowAliases():Boolean { return _config.allowAliases; }
        
        /** @private */
        public function set allowAliases( value:Boolean ):void { _config.allowAliases = value; }
        
        /**
         * Allows to execute function call. if set to false it blocks any functrion call and return undefined.
         * <p><b>Example:</b></p>
         * <pre class="prettyprint">
         * "titi = \"hello world\";
         * toto = titi.toUpperCase();"
         * 
         * // allowFunctionCall = true
         * toto = "HELLO WORLD"
         * 
         * // allowFunctionCall = false
         * toto = undefined
         * </pre>
         */
        public function get allowFunctionCall():Boolean { return _config.allowFunctionCall; }
        
        /** @private */
        public function set allowFunctionCall( value:Boolean ):void { _config.allowFunctionCall = value; }
        
        // TODO : may become obsolete for AS3/ES4 but let's keep it for now for configuration file backward compatibility
        /**
         * When set to false array index are evaluated without bracket eval( test.0 ) for Flash ActionScript
         * When set to true array index are evaluated with bracket eval( test[0] ) for JavaScript, JScript, JSDB etc.
         */
        public function get arrayIndexAsBracket():Boolean { return _config.arrayIndexAsBracket; }
        
        /** @private */
        public function set arrayIndexAsBracket( value:Boolean ):void { _config.arrayIndexAsBracket = value; }
        
        /* note:
           few rules
           - authorized check only for global reference
           - addAuthorized( "library.eden.EdenSerializer" );
             will allow only
             - the assignement of the ref
               test = library.eden.EdenSerializer;
             - the call of the ctor
               test = new library.eden.EdenSerializer();
             you will not be able to call any methods on the instance
           - addAuthorized( "library.eden.EdenSerializer.*" );
             will allow all of the above
             but will also allow the call of methods on the instance
             ex:
             test = new library.eden.EdenSerializer();
             str  = test.toSource();
           - addAuthorized( "library.eden.EdenSerializer.*" );
             and at the same time allowFunctionCall=false
             then you will not be able to call any functions or methods
             and it will behave like addAuthorized( "library.eden.EdenSerializer" );
        */
        /**
         * List of authorized keywords, objects path and constructors that the parser is allowed to interpret.
         * <p>Note: you can add full path</p>
         * <p><b>ex:</b> "blah.foobar"</p>
         * <p>and/or starting path</p>
         * <p><b>ex:</b> "toto.titi.*"</p>
         * <p>The difference is with a full path you can only <b>create/use/define/assign</b> value to this exact path and
         * with a starting path you can create/use/define/assign value to this path and its child paths.</p> 
         * <p><b>Attention:</b> special values as NaN, true, false, null, undefined are always authorized.</p>
         */
        public function get authorized():Array { return _config.authorized; }
        
        /** @private */
        public function set authorized( value:Array ):void { _config.authorized = value; }
        
        /**
         * Parameter to remove (true) or add (false) all unecessary spaces, tabs, carriages returns, lines feeds etc. 
         * to optimize (more or less) packets of datas when they are transfered.
         * <p><b>Note 1 :</b> use "compress = false" when you want to have a better view or debug packets of datas.</p>
         * <p><b>Note 2 :</b> this property is in sync with eden.prettyPrint</p>
         */
        public function get compress():Boolean { return _config.compress; }
        
        /** @private */
        public function set compress( value:Boolean ):void { _config.compress = value; }
        
        /**
         * Parameter allowing to copy objects by value if true or by reference if false.
         * <p><b>Example :</b></p>
         * <code class="prettyprint">
         * foo = {a:1, b:2, c:3};
         * bar = foo;
         * </code>
         * In this case with copyObjectByValue = false
         * bar will be a reference to the foo object
         * but if copyObjectByValue = true
         * bar will be an exact copy of foo object 
         */
        public function get copyObjectByValue():Boolean { return _config.copyObjectByValue; }
        /** @private */
        public function set copyObjectByValue( value:Boolean ):void { _config.copyObjectByValue = value; }
        
        /**
         * List of reserved keywords
         * Reserved words may not be used for variables, functions, methods, or object identifiers.
         * The following are existing reserved keywords defined by the ECMAScript specification.
         */
        public function get reserved():Array { return _config.reserved; }
        /** @private */
        public function set reserved( value:Array ):void { _config.reserved = value; }
        
        /**
         * List of future reserved keywords
         * The following are existing future reserved keywords defined by the ECMAScript specification.
         */
        public function get reservedFuture():Array { return _config.reservedFuture; }
        /** @private */
        public function set reservedFuture( value:Array ):void { _config.reservedFuture = value; }
        
        /**
         * Allows to define the case-sensitivy of the parsers.
         * If true, variable names that differ only in case are considered different.
         */
        public function get strictMode():Boolean
        {
            return _config.strictMode;
        }
        
        /**
         * @private
         */
        public function set strictMode( value:Boolean ):void
        {
            _config.strictMode = value;
        }
        
        /**
         * Value assigned to a variable    when this one is not found or not authorized.
         * Depending on your environment you can override it with a more suitable one for exemple on C# you could set it to null.
         */
        public function get undefineable():*
        {
            return _config.undefineable;
        }
        
        /**
         * @private
         */
        public function set undefineable( value:* ):void
        {
            _config.undefineable = value;
        }
        
        /**
         * Parameter allowing to trace messages in the console if the environment permit it.
         */
        public function get verbose():Boolean
        {
            return _config.verbose;
        }
        
        /**
         * @private
         */
        public function set verbose( value:Boolean ):void
        {
            _config.verbose = value;
        }
        
        /**
         * Parameter setting on (true) or off (false) the security.
         * If true, all object path, function or constructor will be scanned at interpretation time against the authorized list.
         * @see system.serializers.eden.config.authorized.
         */
        public function get security():Boolean
        {
            return _config.security;
        }
        
        /**
         * @private
         */
        public function set security( value:Boolean ):void
        {
            _config.security = value;
        }
    }
}

